home *** CD-ROM | disk | FTP | other *** search
-
- .386P
- code32 segment para public use32
- assume cs:code32,ds:code32
- include 386power.inc
- include 386sys.inc
-
-
- ; RAW KEYBOARD I/O
- ; 32bit section, Keyboard ISR for raw keyboard input
-
- ; Raw KeyBoard table
- ; Every key "description" is made of two consecutive bytes
- ; if a key has a keyboard scancode K
- ; address:
- ; _RKB+(K) bit meaning: description:
- ; 0 IS_PRESSED 0 == key K is currently not pressed
- ; 1 == key K is currently pressed
- ;
- ; 1 TOUCHED 0 == key K has not been pressed
- ; since last time you cleared this bit.
- ; 1 == key K has been pressed
- ;
- ; Use IS_PRESSED for "raw" control (i.e cursor keys in a game)
- ; and TOUCHED (but clear it before!!) for "keyboard-like" control
- ; when you have to choose items in a menu or when
- ; you have to check special "toggle" keys that may be pressed anytime
- ; (i.e. the all time high ESC key)
- public _KeyNames,_NotAKey
-
- _KeyNames dd offset knt
- _NotAKey dd offset boh
- ; n.b. the character code zero is "no key"
- ; so the character number zero is used as a standard message
- ; for key selection "choose key"
-
- knt dd nada,esc,uno,due,tre,quattro,cinque,sei
- dd sette,otto,nove,zero,meno,piu,backspace,tab
- dd q,w,e,r,t,y,u,i
- dd o,p,aquad,cquad,enter,ctrl,a,s
- dd d,f,g,h,j,k,l,puntovirgola_2punti
- dd apice_virgolette,apice_tilde,lshift,slash_bar,z,x,c,v
- dd b,n,m,virgola_maggiore,punto_minore,backslash_interrogativo,rshift,k_per
- dd alt,spazio,capslock,f1,f2,f3,f4,f5
- dd f6,f7,f8,f9,f10,numlock,scrolllock,k_home
- dd k_up,k_pgup,k_meno,k_left,k_five,k_right,k_piu,k_end
- dd k_down,k_pgdn,k_ins,k_del,boh,boh,lshift,f11
- ; boh = code 54h..55h unknow , 56h looks like a left_shift duplicate
- dd f12, boh,boh,boh,boh,boh,boh,boh
- dd boh,boh,boh,boh,boh,boh,boh,boh
- dd boh,boh,boh,boh,boh,boh,boh,key_macro
- dd boh,boh,boh,boh,boh,boh,boh,boh
- dd boh,boh,boh,boh,boh,boh,boh,boh
-
- boh db 'unknown key code',0
- nada db 'not defined',0
- esc db 'ESC',0
- uno db '1',0
- due db '2',0
- tre db '3',0
- quattro db '4',0
- cinque db '5',0
- sei db '6',0
- sette db '7',0
- otto db '8',0
- nove db '9',0
- zero db '0',0
- piu db '+',0
- meno db '-',0
- q db 'q',0
- w db 'w',0
- e db 'e',0
- r db 'r',0
- t db 't',0
- y db 'y',0
- u db 'u',0
- i db 'i',0
- o db 'o',0
- p db 'p',0
- a db 'a',0
- s db 's',0
- d db 'd',0
- f db 'f',0
- g db 'g',0
- h db 'h',0
- j db 'j',0
- k db 'k',0
- l db 'l',0
- z db 'z',0
- x db 'x',0
- c db 'c',0
- v db 'v',0
- b db 'b',0
- n db 'n',0
- m db 'm',0
- aquad db '[',0
- cquad db ']',0
- tab db 'TAB',0
-
- backspace db 'BACKSPACE',0
- enter db 'ENTER',0
- ctrl db 'CTRL',0
- puntovirgola_2punti db ';',0
- apice_virgolette db '"',0
- apice_tilde db '~',0
- lshift db 'LEFT SHIFT',0
- slash_bar db '\',0
- virgola_maggiore db ',',0
- punto_minore db '.',0
- backslash_interrogativo db '/',0
- rshift db 'RIGHT SHIFT',0
- k_per db 'KEYPAD *',0
- alt db 'ALT',0
- spazio db 'SPACE',0
- capslock db 'CAPSLOCK',0
-
- f1 db 'fn 1',0
- f2 db 'fn 2',0
- f3 db 'fn 3',0
- f4 db 'fn 4',0
- f5 db 'fn 5',0
- f6 db 'fn 6',0
- f7 db 'fn 7',0
- f8 db 'fn 8',0
- f9 db 'fn 9',0
- f10 db 'fn 10',0
- f11 db 'fn 11',0
- f12 db 'fn 12',0
-
- numlock db 'NUMLOCK',0
- scrolllock db 'SCROLL LOCK',0
- k_home db 'HOME',0
- k_up db 'CURSOR UP',0
- k_pgup db 'PAGE UP',0
- k_meno db 'keypad -',0
- k_left db 'CURSOR LEFT',0
- k_five db 'keypad 5',0
- k_right db 'CURSOR RIGHT',0
- k_piu db 'keypad +',0
- k_end db 'END',0
- k_down db 'CURSOR DOWN',0
- k_pgdn db 'PAGE DOWN',0
- k_ins db 'INS',0
- k_del db 'DEL',0
- key_macro db 'MACRO KEY',0
-
- _RKB db 128 dup(0)
-
- RKBPressed db 0 ; 0 == no keys pressed since last time you reset this flag
- ; 1 == something happened, a key has been pressed
- ; (this is like a "general" TOUCHED flag)
- ezero db 0
-
- IRQ1_ISR:
- cli
- push eax
- push ebx
- push ds
- mov ds,cs:_SelData
-
- in al,60h ; get scan code
-
- movzx ebx,al ; move scan code to index register
-
- in al,61h ; get control code
- push eax
- or al,80h ; clear keyboard of interrupt:
- out 61h,al ;
- pop eax ; first send control byte with inverted MSB
- out 61h,al ; then send plain control byte
-
- mov al,EOI ; send generic EOI to
- out PIC0_CTRL,al ; PIC
- ; enabling other interrupts
-
- cmp al,0E0h ; the terrific escape code
- jne good_k
- mov ezero,1
- jmp short guuk
- good_k:
- cmp ezero,0 ; does previous key was multi-byte prefix ?
- je noezero ;
- mov ezero,0
- ; skip false keypresses
- cmp al,0AAh
- je guuk
- cmp al,02ah
- je guuk
- cmp al,0B6h
- je guuk
- cmp al,036h
- je guuk
- noezero:
- mov al,bl
- and bl,07Fh
- ; if the key was released, the high bit is set in the scan code
-
- ; first of all, let's assume it was released
- mov byte ptr[ebx+offset _RKB],02h ; reset "Is being pressed" flag
- ; and set again "Has been pressed"
- ; N.B. FOLLOW STRICTLY THIS METHOD
- ;
-
- rol al,1 ; has it been released ?
- jc key_released ;
- ; no, it has been pressed
- mov byte ptr [ebx+offset _RKB],03h ; set "Is being pressed" flag
- ; and "Has been pressed" flag
- key_released:
- mov RKBPressed,1 ; state of keyboard has changed
- guuk:
- sti
- pop ds
- pop ebx
- pop eax
- iretd
-
- public _WaitKey
- _WaitKey dd offset WaitKey
-
- WaitKey:
- ; WAITS UNTIL A KEY IS PRESSED
- ; then returns pointer to keyboard table
- mov RKBPressed,0
- @waitmore:
- test RKBPressed,1
- jz @waitmore
- mov eax,offset _RKB
- ret
-
-
-
- KEYB_EXIT: ; 386keyb termination code
- ; restore default keyboard handler and rate
- call KeybAsciiMode ; restore default keyboard handler
- ; THIS CODE NOW HAS BEEN MOVED BACK TO THE MAIN EXIT ROUTINE
- ; BECAUSE IT BOMBED UNDER PROT. MODE WITH MY ANTIVIRUS LOADED
- ;sti
- ; now set typematic rate to the default values
- mov V86ax,0305h ; typematic_rate set_rate
- mov V86bx,000Ch ; 00 == 250msec delay_value
- ; 0C == 10char/sec repeat_rate
- mov al,16h
- call _ExecINT
- ;cli
- ret
-
- public _KeybInst
- _KeybInst dd offset InstallRKB
-
- plaintty dd 0
-
- InstallRKB:
- pushad
-
- ; Now set typematic rate to the lowest values
- mov V86ax,0305h ; typematic_rate set_rate
- mov V86bx,001Fh ; 00 == 250msec delay_value
- ; 1F == 2char/sec repeat_rate
- mov al,16h
- call _ExecINT
-
- mov bl,1
- call _GetIRQ
- mov plaintty,edx ; get the default irq handler
-
- mov eax, offset KEYB_EXIT ; set exit function
- call _OnExit ;
-
- mov eax,0
- mov edi,offset _RKB
- mov ecx,32 ; 128bytes == 32 dwords
- rep stosd
-
- call _KeybRawMode
-
- popad
- ret
-
- public _KeybAsciiMode
- _KeybAsciiMode dd offset KeybAsciiMode
- KeybAsciiMode:
- pushad
- mov bl,1
- mov edx,plaintty
- call _SetIRQ
- popad
- ret
-
- public _KeybRawMode
- _KeybRawMode dd offset KeybRawMode
- KeybRawMode:
- pushad
- mov bl,1
- mov edx,offset IRQ1_ISR
- call _SetIRQ
- popad
- ret
-
- public _ScanKeyb
- _ScanKeyb dd offset ScanKeyb
- ScanKeyb:
- mov eax,offset _RKB
- ret
-
- public _ReadAscii
- _ReadAscii dd offset ReadAscii
- ReadAscii: ; out: eax = ascii char read from consolle
- ; Be careful! this uses int 09 (irq 1)
- ; so it needs _KeybAsciiMode !!!
- push V86eax
- retry:
- mov eax,21h ; get a key thru dos & reset upper bytes of eax
- mov V86ah,07 ;
- call _ExecINT ;
- mov al,V86al ;
- or al,al ;
- je retry ; NUL character, retry
- pop V86eax
- ret
- code32 ends
-
- END
-